﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.IO;
using System.Threading;
using System.Xml.Linq;
using System.Xml;
using System.Windows.Threading;
namespace E.Silverlight.Study
{
    public partial class MainPage : UserControl
    {
        // 异常信息
        string _exception = "";

        string cid = "";

        int index_page = 1;

        int book_page = 1;

        double proress = 0;

        // SynchronizationContext - 同步上下文管理类
        SynchronizationContext _syncContext;
        //课件model
        CourseWareModel model = new CourseWareModel();

        //使用计时器对象来更新播放进度
        private DispatcherTimer timer = new DispatcherTimer();
        // 媒体的时长
        private TimeSpan duration;


        public MainPage()
        {
            try
            {
                cid = App.Current.Host.InitParams["cid"];
                //cid="141$8";
                string _url = string.Format("http://{0}/tools/ajax.aspx?t=getCourseWareList&cid={1}", App.Current.Host.Source.AbsoluteUri.Split('/')[2], cid.Split('$')[0]);
                //string _url = string.Format("http://{0}/tools/ajax.aspx?t=getCourseWareList&cid={1}", "localhost:3647", cid.Split('$')[0]);
                GetXML(_url);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
            }

            InitializeComponent();

        }


        #region request

        void GetXML(string url)
        {
            // SynchronizationContext.Current - 当前线程的同步上下文
            _syncContext = SynchronizationContext.Current;
            /*

             * HttpWebRequest - 对指定的 URI 发出请求

             *     HttpWebRequest.Create(uri) - 初始化一个 WebRequest

             *     HttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state) - 开始对指定 URI 资源做异步请求

             *         AsyncCallback callback - System.AsyncCallback 委托。异步操作完成时调用的回调方法

             *         Object state - 包含此异步请求的对象。即相应的 HttpWebRequest 对象

             *     HttpWebRequest.Abort() - 取消该异步请求

             *     HttpWebRequest.Accept - HTTP 头的 Accept  部分

             *     HttpWebRequest.ContentType - HTTP 头的 ContentType 部分

             *     HttpWebRequest.Headers - HTTP 头的 key/value 对集合

             *     HttpWebRequest.Method - HTTP 方法（只支持GET和POST）

             *     HttpWebRequest.RequestUri - 所请求的 URI

             *     HttpWebRequest.HaveResponse - 是否接收到了指定 URI 的响应

             *     HttpWebRequest.AllowReadStreamBuffering - 是否对从 Internet 资源接收的数据做缓冲处理。默认值为true，将数据缓存在客户端内存中，以便随时被应用程序读取

             */
            HttpWebRequest request = WebRequest.Create(
                new Uri(url, UriKind.Absolute)) as HttpWebRequest;
            request.Method = "GET";
            request.BeginGetResponse(new AsyncCallback(ResponseCallback), request);

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="result">IAsyncResult.AsyncState - AsyncCallback 传过来的对象</param>
        private void ResponseCallback(IAsyncResult result)
        {
            HttpWebRequest request = result.AsyncState as HttpWebRequest;
            WebResponse response = null;
            try
            {
                // HttpWebRequest.EndGetResponse(IAsyncResult) - 结束对指定 URI 资源做异步请求
                //     返回值为 WebResponse 对象
                response = request.EndGetResponse(result) as HttpWebResponse;
            }
            catch (Exception ex)
            {
                _exception = ex.ToString();
            }
            // SynchronizationContext.Post(SendOrPostCallback d, Object state) - 将异步消息发送到该同步上下文中
            //     SendOrPostCallback d - System.Threading.SendOrPostCallback 委托
            //     Object state - 需要传递的参数
            _syncContext.Post(GetResponse, response);
        }

        /// <summary>
        /// HttpWebResponse - 对指定的 URI 做出响应
        /// GetResponseStream() - 获取响应的数据流
        /// </summary>
        /// <param name="state"></param>
        private void GetResponse(object state)
        {
            HttpWebResponse response = state as HttpWebResponse;
            if (response != null)
            {
                Stream responseStream = response.GetResponseStream();
                using (StreamReader sr = new StreamReader(responseStream))
                {
                    string xml = sr.ReadToEnd();
                    getCourseWareList(xml);
                }
            }
            else
            {
                MessageBox.Show(_exception);
            }
        }

        void SetBookXML(string url)
        {
            // SynchronizationContext.Current - 当前线程的同步上下文
            _syncContext = SynchronizationContext.Current;
            /*

             * HttpWebRequest - 对指定的 URI 发出请求

             *     HttpWebRequest.Create(uri) - 初始化一个 WebRequest

             *     HttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state) - 开始对指定 URI 资源做异步请求

             *         AsyncCallback callback - System.AsyncCallback 委托。异步操作完成时调用的回调方法

             *         Object state - 包含此异步请求的对象。即相应的 HttpWebRequest 对象

             *     HttpWebRequest.Abort() - 取消该异步请求

             *     HttpWebRequest.Accept - HTTP 头的 Accept  部分

             *     HttpWebRequest.ContentType - HTTP 头的 ContentType 部分

             *     HttpWebRequest.Headers - HTTP 头的 key/value 对集合

             *     HttpWebRequest.Method - HTTP 方法（只支持GET和POST）

             *     HttpWebRequest.RequestUri - 所请求的 URI

             *     HttpWebRequest.HaveResponse - 是否接收到了指定 URI 的响应

             *     HttpWebRequest.AllowReadStreamBuffering - 是否对从 Internet 资源接收的数据做缓冲处理。默认值为true，将数据缓存在客户端内存中，以便随时被应用程序读取

             */
            HttpWebRequest request = WebRequest.Create(
                new Uri(url, UriKind.Absolute)) as HttpWebRequest;
            request.Method = "GET";
            request.BeginGetResponse(new AsyncCallback(ResponseCallback2), request);

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="result">IAsyncResult.AsyncState - AsyncCallback 传过来的对象</param>
        private void ResponseCallback2(IAsyncResult result)
        {
            HttpWebRequest request = result.AsyncState as HttpWebRequest;
            WebResponse response = null;
            try
            {
                // HttpWebRequest.EndGetResponse(IAsyncResult) - 结束对指定 URI 资源做异步请求
                //     返回值为 WebResponse 对象
                response = request.EndGetResponse(result) as HttpWebResponse;
            }
            catch (Exception ex)
            {
                _exception = ex.ToString();
            }
            // SynchronizationContext.Post(SendOrPostCallback d, Object state) - 将异步消息发送到该同步上下文中
            //     SendOrPostCallback d - System.Threading.SendOrPostCallback 委托
            //     Object state - 需要传递的参数
            _syncContext.Post(GetResponse2, response);
        }

        /// <summary>
        /// HttpWebResponse - 对指定的 URI 做出响应
        /// GetResponseStream() - 获取响应的数据流
        /// </summary>
        /// <param name="state"></param>
        private void GetResponse2(object state)
        {
            HttpWebResponse response = state as HttpWebResponse;
            if (response != null)
            {
                Stream responseStream = response.GetResponseStream();
                using (StreamReader sr = new StreamReader(responseStream))
                {
                    string xml = sr.ReadToEnd();
                    MessageBox.Show("设置书签成功！");
                }
            }
            else
            {
                MessageBox.Show(_exception);
            }
        }

        void SetProcessXML(string url)
        {
            // SynchronizationContext.Current - 当前线程的同步上下文
            _syncContext = SynchronizationContext.Current;
            /*

             * HttpWebRequest - 对指定的 URI 发出请求

             *     HttpWebRequest.Create(uri) - 初始化一个 WebRequest

             *     HttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state) - 开始对指定 URI 资源做异步请求

             *         AsyncCallback callback - System.AsyncCallback 委托。异步操作完成时调用的回调方法

             *         Object state - 包含此异步请求的对象。即相应的 HttpWebRequest 对象

             *     HttpWebRequest.Abort() - 取消该异步请求

             *     HttpWebRequest.Accept - HTTP 头的 Accept  部分

             *     HttpWebRequest.ContentType - HTTP 头的 ContentType 部分

             *     HttpWebRequest.Headers - HTTP 头的 key/value 对集合

             *     HttpWebRequest.Method - HTTP 方法（只支持GET和POST）

             *     HttpWebRequest.RequestUri - 所请求的 URI

             *     HttpWebRequest.HaveResponse - 是否接收到了指定 URI 的响应

             *     HttpWebRequest.AllowReadStreamBuffering - 是否对从 Internet 资源接收的数据做缓冲处理。默认值为true，将数据缓存在客户端内存中，以便随时被应用程序读取

             */
            HttpWebRequest request = WebRequest.Create(
                new Uri(url, UriKind.Absolute)) as HttpWebRequest;
            request.Method = "GET";
            request.BeginGetResponse(new AsyncCallback(ResponseCallback3), request);

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="result">IAsyncResult.AsyncState - AsyncCallback 传过来的对象</param>
        private void ResponseCallback3(IAsyncResult result)
        {
            HttpWebRequest request = result.AsyncState as HttpWebRequest;
            WebResponse response = null;
            try
            {
                // HttpWebRequest.EndGetResponse(IAsyncResult) - 结束对指定 URI 资源做异步请求
                //     返回值为 WebResponse 对象
                response = request.EndGetResponse(result) as HttpWebResponse;
            }
            catch (Exception ex)
            {
                _exception = ex.ToString();
            }
            // SynchronizationContext.Post(SendOrPostCallback d, Object state) - 将异步消息发送到该同步上下文中
            //     SendOrPostCallback d - System.Threading.SendOrPostCallback 委托
            //     Object state - 需要传递的参数
            _syncContext.Post(GetResponse3, response);
        }

        /// <summary>
        /// HttpWebResponse - 对指定的 URI 做出响应
        /// GetResponseStream() - 获取响应的数据流
        /// </summary>
        /// <param name="state"></param>
        private void GetResponse3(object state)
        {
            HttpWebResponse response = state as HttpWebResponse;
            if (response != null)
            {
                Stream responseStream = response.GetResponseStream();
                using (StreamReader sr = new StreamReader(responseStream))
                {
                    string xml = sr.ReadToEnd();
                    MessageBox.Show("同步进度成功！");
                }
            }
            else
            {
                MessageBox.Show(_exception);
            }
        }

        #endregion

        private void getCourseWareList(string xml)
        {
            try
            {
                model = new CourseWareModel();
                Byte[] b = System.Text.UTF8Encoding.UTF8.GetBytes(xml);
                XDocument xele = XDocument.Load(System.Xml.XmlReader.Create(new MemoryStream(b)));
                XElement data = (from item in xele.Descendants("Data") select item).First();
                XElement courseInfo = (from item in data.Descendants("CourseInfo") select item).First();
                courseName.Text = courseInfo.Attribute(XName.Get("CourseName")).Value;
                book_page = int.Parse(courseInfo.Attribute(XName.Get("BookMark")).Value);
                proress = double.Parse(courseInfo.Attribute(XName.Get("Process")).Value);
                XElement courseware = (from item in data.Descendants("CourseWare") select item).First();
                XElement info = (from item in courseware.Descendants("Info") select item).First();
                model.ID = int.Parse(info.Element(XName.Get("ID")).Value);
                model.SerialNumber = int.Parse(info.Element(XName.Get("SerialNumber")).Value);
                model.ImgUrl = info.Element(XName.Get("ImgUrl")).Value;
                model.SoundUrl = info.Element(XName.Get("SoundUrl")).Value;
                model.VideoUrl = info.Element(XName.Get("VideoUrl")).Value;
                model.Content = info.Element(XName.Get("Content")).Value;
                content.Text = model.Content;
                totalPages.Text = "/ " + model.SerialNumber.ToString();



                button1.IsEnabled = true;
                button2.IsEnabled = true;
                button3.IsEnabled = true;
                button4.IsEnabled = true;
                pageTextBox.IsEnabled = true;
                pptButton.IsEnabled = true;
                pptButton.IsChecked = true;
                if (book_page >= 1 && book_page <= model.SerialNumber)
                    index_page = book_page;

                if (index_page == model.SerialNumber)
                    button2.IsEnabled = false;
                if (index_page == 1)
                    button1.IsEnabled = false;

                if (model.VideoUrl != "" || model.SoundUrl != "")
                {
                    videoButton.IsEnabled = true;
                }

                if (model.SoundUrl != "")
                {
                    //soundBorder.Visibility = System.Windows.Visibility.Visible;
                    //media.Source = new Uri(model.SoundUrl);
                }
                else
                {
                    soundItem.Visibility = System.Windows.Visibility.Collapsed;
                }

                this.loadpic(index_page);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
            }

        }

        void loadpic(int page)
        {
            pageTextBox.Text = page.ToString();
            BitmapImage bi = new BitmapImage();
            image1.Source = bi;
            bi.DownloadProgress += new EventHandler<DownloadProgressEventArgs>(bi_DownloadProgress);
            try
            {
                string url = string.Format("{0}/{1}.jpg", model.ImgUrl.Substring(0, model.ImgUrl.LastIndexOf('.')), page);
                busy.IsBusy = true;
                bi.UriSource = new Uri(url);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
            }
        }

        void bi_DownloadProgress(object sender, DownloadProgressEventArgs e)
        {
            if (e.Progress == 100)
                busy.IsBusy = false;
        }

        private void pageTextBox_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                try
                {
                    int to = int.Parse(pageTextBox.Text);
                    index_page = to;

                    button2.IsEnabled = true;
                    button2.IsEnabled = true;
                    if (to >= 1 && to <= model.SerialNumber)
                    {
                        if (index_page == model.SerialNumber)
                            button2.IsEnabled = false;
                        if (index_page == 1)
                            button1.IsEnabled = false;


                        loadpic(index_page);
                    }
                    else
                    {
                        MessageBox.Show("输入的页码有错误！");
                        pageTextBox.Text = index_page.ToString();
                    }
                }
                catch
                {
                    MessageBox.Show("输入的页码有错误！");
                    pageTextBox.Text = index_page.ToString();
                }
            }
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            index_page--;
            if (index_page >= 1)
            {
                if (index_page == 1)
                    button1.IsEnabled = false;
                if (index_page < model.SerialNumber)
                    button2.IsEnabled = true;
                loadpic(index_page);
            }
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            index_page++;
            if (index_page <= model.SerialNumber)
            {
                if (index_page == model.SerialNumber)
                    button2.IsEnabled = false;
                if (index_page > 1)
                    button1.IsEnabled = true;
                loadpic(index_page);
            }
        }

        private void button3_Click(object sender, RoutedEventArgs e)
        {
            try
            {

                string _url = string.Format("http://{0}/tools/ajax.aspx?t=setBookMark&courseid={1}&pagenumber={2}", App.Current.Host.Source.AbsoluteUri.Split('/')[2], cid.Split('$')[0], index_page);
                SetBookXML(_url);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
            }

        }

        private void button4_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                double p = Math.Floor(index_page * 100 / model.SerialNumber);
                if (proress < p)
                {
                    //string _url = string.Format("http://{0}/tools/ajax.aspx?t=getCourseWareList&cid={1}", App.Current.Host.Source.AbsoluteUri.Split('/')[2], cid.Split('$')[0]);
                    string _url = string.Format("http://{0}/tools/ajax.aspx?t=setInternalStudyProcess&courseid={1}&projectid={2}&process={3}", App.Current.Host.Source.AbsoluteUri.Split('/')[2], cid.Split('$')[0], cid.Split('$')[1], p);
                    SetProcessXML(_url);
                }
                else
                {
                    MessageBox.Show("同步进度成功！");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
            }
        }

        private void pptButton_Click(object sender, RoutedEventArgs e)
        {
            if (videoBorder.Opacity != 0)
            {
                tmedia.Pause();
                sbClose.Begin();
                sbClose.Completed += (s, ex) =>
                {
                    flowBorder.Visibility = System.Windows.Visibility.Collapsed;
                    videoBorder.Visibility = System.Windows.Visibility.Collapsed;
                };
            }

        }

        private void videoButton_Click(object sender, RoutedEventArgs e)
        {
            if (videoBorder.Opacity != 1)
            {
                if (mediaItem.Source == null)
                {
                    mediaItem.Source = new Uri(model.VideoUrl);
                }
                if (soundItem.Source == null && model.SoundUrl != "")
                {
                    soundItem.Source = new Uri(model.SoundUrl);
                }
                flowBorder.Visibility = System.Windows.Visibility.Visible;
                videoBorder.Visibility = System.Windows.Visibility.Visible;
                sbDisplay.Begin();
            }
        }


        #region sound 弃用
        private void btnPlay_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // 播放
            media.Play();
        }

        private void btnPause_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // 暂停
            media.Pause();
        }

        private void btnStop_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            //停止
            media.Stop();
        }

        private void cbSilent_Checked(object sender, System.Windows.RoutedEventArgs e)
        {
            // 静音
            media.IsMuted = true;
        }

        private void cbSilent_Unchecked(object sender, System.Windows.RoutedEventArgs e)
        {
            // 不静音
            media.IsMuted = false;
        }

        private void Slider_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
        {
            //确定多媒体对象的播放位置是否处于可管理状态
            if (media.CanSeek)
            {
                //重新设置MediaElement的播放位置
                media.Position = TimeSpan.FromSeconds((media.NaturalDuration.TimeSpan.TotalSeconds * slider1.Value) / 10);
            }
        }

        private void media_BufferingProgressChanged(object sender, System.Windows.RoutedEventArgs e)
        {
            // 视频缓冲事件
            double bufferingValue = this.media.BufferingProgress * 100;
            this.tbBufferingdValue.Text = "缓冲 : " + bufferingValue.ToString() + "%";
            if (this.tbBufferingdValue.Text == "缓冲 : 100%")
            {
                //隐藏缓冲值
                this.tbBufferingdValue.Visibility = Visibility.Collapsed;
            }
        }

        private void media_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            //设置事件引发的时间间隔
            timer.Interval = TimeSpan.FromMilliseconds(500);
            //计时器对象事件
            timer.Tick += new EventHandler(timer_Tick);
            //开始计时
            timer.Start();

            //设置音量
            media.Volume = 0.8;
            sliderVolumn.Value = 0.8;

        }

        private void timer_Tick(object sender, System.EventArgs e)
        {
            //当前处于播放时有效
            if (this.media.CurrentState == MediaElementState.Playing)
            {
                duration = media.NaturalDuration.HasTimeSpan ? media.NaturalDuration.TimeSpan : TimeSpan.FromMilliseconds(0);
                this.tbCurrentTime.Text = string.Format("{0}:{1}:{2}", media.Position.Hours < 10 ? "0" + media.Position.Hours.ToString() : media.Position.Hours.ToString(), media.Position.Minutes < 10 ? "0" + media.Position.Minutes.ToString() : media.Position.Minutes.ToString(), media.Position.Seconds < 10 ? "0" + media.Position.Seconds.ToString() : media.Position.Seconds.ToString());
                this.tbTotalTime.Text = string.Format(
                "{0}{1:00}:{2:00}:{3:00}", "/ ",
                duration.Hours,
                duration.Minutes,
                duration.Seconds);
                //跳过事件处理程序
                slider1.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(Slider_ValueChanged);
                //计算并设置Slider的百分比
                slider1.Value = (media.Position.TotalSeconds / media.NaturalDuration.TimeSpan.TotalSeconds) * 10;
                //重新声明ValueChanged事件
                slider1.ValueChanged += new RoutedPropertyChangedEventHandler<double>(Slider_ValueChanged);
            }
        }

        private void sliderVolumn_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
        {
            // 音量发生改变触发事件
            media.Volume = sliderVolumn.Value;
        }



        #endregion

        private void media_MediaFailed(object sender, ExceptionRoutedEventArgs e)
        {
            MessageBox.Show(e.ErrorException.Message);
        }

    }
}
